package com.san.oms.dao;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.druid.pool.DruidPooledPreparedStatement;
import com.san.base.dao.BaseManager;
import com.san.common.datasource.JdbcManager;
import com.san.common.utils.Constant;
import com.san.common.utils.QuotaRuleComparator;
import com.san.common.utils.StringUtils;
import com.san.metadata.domain.BaseLegalPersonDO;
import com.san.metadata.domain.BaseNaturalPersonDO;
import com.san.metadata.domain.DataSourceDO;
import com.san.metadata.service.BaseLegalPersonService;
import com.san.metadata.service.BaseNaturalPersonService;
import com.san.metadata.service.DataSourceService;
import com.san.oms.domain.ModelScDTO;
import com.san.oms.domain.QuotaDO;
import com.san.oms.domain.QuotaRuleDTO;
import com.san.oms.domain.ScoreDTO;
import com.san.oms.domain.ScoreLevelDetailDO;
import com.san.oms.service.ModelService;
import com.san.oms.service.QuotaService;
import com.san.oms.service.ScoreLevelDetailService;

/**
 * 模型评分计算JDBC访问层
 * 
 * @author xiangyz
 *
 */
@Service
public abstract class ScoreManager extends BaseManager {

	private static final Logger logger = LoggerFactory.getLogger(ScoreManager.class);

	@Autowired
	DataSourceService dataSourceService;

	@Autowired
	ModelService modelService;

	@Autowired
	QuotaService quotaService;

	@Autowired
	BaseLegalPersonService baseLegalPersonService;

	@Autowired
	BaseNaturalPersonService baseNaturalPersonService;

	@Autowired
	ScoreLevelDetailService scoreLevelDetailService;

	/**
	 * 备份表
	 * 
	 * @param modelDTO
	 * @return
	 * @throws Exception
	 */
	public abstract boolean bakTable(ModelScDTO modelDTO) throws Exception;

	/**
	 * 获取模型指标关联业务元数据中的最大值，区间算法未指定规则时使用
	 * 
	 * @param modelType
	 * @param quotaDO
	 * @return
	 * @throws Exception
	 */
	public abstract String getMaxValue(int modelType, QuotaDO quotaDO) throws Exception;

	/**
	 * 获取模型指标关联业务元数据中的最小值，加权算法未指定系数时使用
	 * 
	 * @param modelType
	 * @param quotaDO
	 * @return
	 * @throws Exception
	 */
	public abstract String getMinValue(int modelType, QuotaDO quotaDO) throws Exception;

	/**
	 * 保存父级指标分数
	 * 
	 * @param modelDTO       模型评分DTO
	 * @param quotaDO        模型指标DO
	 * @param childQuotaList 子指标
	 * @throws Exception
	 */
	public abstract void saveParentQuotaScore(ModelScDTO modelDTO, QuotaDO quotaDO, List<QuotaDO> childQuotaList)
			throws Exception;

	/**
	 * 获取基础数据源信息
	 * 
	 * @return
	 */
	public DataSourceDO getBaseDataSource() {
		DataSourceDO dataScourceDO = null;
		try {
			dataScourceDO = dataSourceService.getByCode(Constant.SOURCE_CODE_BASESOURCE);
		} catch (Exception e) {
			logger.error("获取基础数据源失败", e);
		}
		return dataScourceDO;
	}

	/**
	 * 根据模型类型返回法人或自然人关键词
	 * 
	 * @param modelDO
	 * @return
	 */
	public String getInfix(int modelType) {
		// 表及字段中法人/自然人关键词
		String infix = "";
		if (Constant.MODEL_TYPE_LEGAL_PERSON == modelType) {
			infix = "legal";
		} else if (Constant.MODEL_TYPE_NATURAL_PERSON == modelType) {
			infix = "natural";
		} else {
			return null;
		}
		return infix;
	}

	/**
	 * 加权计算
	 * 
	 * @param modelDO
	 * @param quotaDO
	 * @throws Exception
	 */
	public void weightCacl(ModelScDTO modelDTO, QuotaDO quotaDO) throws Exception {
		// 表及字段中法人/自然人关键词
		String infix = this.getInfix(modelDTO.getModelType());
		if (StringUtils.isEmpty(infix)) {
			return;
		}

		String querySQL = "select " + infix + "_person_id,busi_id,busi_value from result_" + infix
				+ "_person where busi_id = ?";

		DruidPooledConnection conn = this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE);

		JdbcManager jdbcManager = new JdbcManager();

		Map<String, Object> queryMap = jdbcManager.executeQueryByType(conn, querySQL,
				new Object[] { quotaDO.getBusiId() });

		ResultSet rs = (ResultSet) queryMap.get("rs");
		DruidPooledPreparedStatement ps = (DruidPooledPreparedStatement) queryMap.get("ps");

		try {
			String tableName = "oms_" + infix + "_score_" + modelDTO.getModelId();
			String insertSQL = "insert into " + tableName + " (" + infix + "_person_id,quota_id,score) values(?,?,?)";

			// 分数格式化保留两位小数
			DecimalFormat df = new DecimalFormat("#.00");
			BigDecimal num = null;
			BigDecimal quotaRule = null;
			BigDecimal score = null;
			BigDecimal minValue = null;
			if (StringUtils.isEmpty(quotaDO.getQuotaRule())) {
				String min = this.getMinValue(modelDTO.getModelType(), quotaDO);
				if (!StringUtils.isEmpty(min)) {
					minValue = new BigDecimal(min);
				}
			}
			BigDecimal quotaScore = new BigDecimal(String.valueOf(quotaDO.getQuotaScore()));
			List<Object[]> listParams = new ArrayList<Object[]>();
			while (rs.next()) {
				try {
					quotaRule = new BigDecimal(
							StringUtils.isEmpty(quotaDO.getQuotaRule()) ? "1" : quotaDO.getQuotaRule());
					num = new BigDecimal(StringUtils.isEmpty((String) rs.getObject("busi_value")) ? "0"
							: (String) rs.getObject("busi_value"));
				} catch (Exception e) {
					System.out.println(rs.getObject(infix + "_person_id") + "   " + quotaDO.getQuotaId());
					e.printStackTrace();
					// TODO 错误日志
				}
				if (null != minValue) {
					// 没有配置系数，则系数=最小值/当前值
					score = num.multiply(minValue.divide(num));
				} else {
					score = num.multiply(quotaRule);
				}

				if (quotaDO.getQuotaScore() >= 0) {
					score = score.compareTo(quotaScore) > 0 ? quotaScore : score;
				} else {
					score = score.compareTo(quotaScore) < 0 ? quotaScore : score;
				}

				listParams.add(
						new Object[] { rs.getObject(infix + "_person_id"), quotaDO.getQuotaId(), df.format(score) });

				if (listParams.size() > COMMIT_SIZE) {
					jdbcManager.batchExecuteSQL(this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), insertSQL,
							listParams);
					listParams = new ArrayList<Object[]>();
				}
			}

			if (listParams.size() > 0) {
				jdbcManager.batchExecuteSQL(this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), insertSQL,
						listParams);
				listParams = new ArrayList<Object[]>();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (null != ps) {
				ps.close();
			}
			if (null != conn) {
				conn.close();
			}
		}
	}

	/**
	 * 区间计算
	 * 
	 * @param modelDO
	 * @param quotaDO
	 * @throws Exception
	 */
	public void intervalCacl(ModelScDTO modelDTO, QuotaDO quotaDO) throws Exception {

		// 表及字段中法人/自然人关键词
		String infix = this.getInfix(modelDTO.getModelType());
		if (StringUtils.isEmpty(infix)) {
			return;
		}

		List<QuotaRuleDTO> list = resolveInterval(quotaDO.getQuotaRule());

		JdbcManager jdbcManager = new JdbcManager();

		BigDecimal maxValue = null;
		if (null == list) {
			maxValue = new BigDecimal(this.getMaxValue(modelDTO.getModelType(), quotaDO));
		}

		String querySQL = "select " + infix + "_person_id,busi_id,busi_value from result_" + infix
				+ "_person where busi_id = ?";

		DruidPooledConnection conn = this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE);

		Map<String, Object> queryMap = jdbcManager.executeQueryByType(conn, querySQL,
				new Object[] { quotaDO.getBusiId() });

		ResultSet rs = (ResultSet) queryMap.get("rs");
		DruidPooledPreparedStatement ps = (DruidPooledPreparedStatement) queryMap.get("ps");

		try {
			String tableName = "oms_" + infix + "_score_" + modelDTO.getModelId();
			String insertSQL = "insert into " + tableName + " (" + infix + "_person_id,quota_id,score) values(?,?,?)";

			// 分数格式化保留两位小数
			DecimalFormat df = new DecimalFormat("#.00");
			BigDecimal num = null;
			BigDecimal score = null;
			BigDecimal quotaScore = new BigDecimal(quotaDO.getQuotaScore() + "");

			// 默认系数，当且仅当区间没有配置，指标值最大数为0时使用
			BigDecimal ratio = new BigDecimal("0.6");
			List<Object[]> listParams = new ArrayList<Object[]>();
			while (rs.next()) {

				try {
					num = new BigDecimal(StringUtils.isEmpty((String) rs.getObject("busi_value")) ? "0"
							: (String) rs.getObject("busi_value"));
				} catch (Exception e) {
					System.out.println(rs.getObject(infix + "_person_id") + "   " + quotaDO.getQuotaId());
					e.printStackTrace();
					// TODO 错误日志
				}

				if (null == list) {
					if (maxValue.doubleValue() == 0) {
						score = quotaScore.multiply(ratio);
					}
					score = num.divide(maxValue);
				} else {
					for (QuotaRuleDTO ruleDTO : list) {
						if (num.compareTo(new BigDecimal(String.valueOf(ruleDTO.getNum()))) <= 0) {
							score = new BigDecimal(ruleDTO.getScore() + "");
							break;
						}
					}
				}

				if (quotaDO.getQuotaScore() > 0) {
					if (score.compareTo(quotaScore) >= 0) {
						score = quotaScore;
					}
				} else {
					if (score.compareTo(quotaScore) < 0) {
						score = quotaScore;
					}
				}

				listParams.add(
						new Object[] { rs.getObject(infix + "_person_id"), quotaDO.getQuotaId(), df.format(score) });

				if (listParams.size() > COMMIT_SIZE) {
					jdbcManager.batchExecuteSQL(this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), insertSQL,
							listParams);
					listParams = new ArrayList<Object[]>();
				}
			}

			if (listParams.size() > 0) {
				jdbcManager.batchExecuteSQL(this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), insertSQL,
						listParams);
				listParams = new ArrayList<Object[]>();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (null != ps) {
				ps.close();
			}
			if (null != conn) {
				conn.close();
			}
		}

	}

	/**
	 * 区间规则转换
	 * 
	 * @param quotaRule
	 * @return
	 * @throws Exception
	 */
	public static List<QuotaRuleDTO> resolveInterval(String quotaRule) throws Exception {
		if (null == quotaRule || "".equals(quotaRule)) {
			return null;
		}
		String[] rules = quotaRule.split("\\|");
		List<QuotaRuleDTO> list = new ArrayList<QuotaRuleDTO>();

		QuotaRuleDTO dto = null;
		for (String rule : rules) {
			String[] section = rule.split(",");
			dto = new QuotaRuleDTO();

			dto.setNum(section[0].equals("~") ? 999999999 : Integer.parseInt(section[0]));
			dto.setScore(Integer.parseInt(section[1]));
			list.add(dto);
		}

		Collections.sort(list, new QuotaRuleComparator());
		return list;

	}

	/**
	 * 查询信用分详情
	 * 
	 * @param modelId 模型ID
	 * @param name    法人名称/自然人姓名
	 * @param code    统一社会信用代码/自然人身份证号码
	 * @throws Exception
	 */
	public List<ScoreDTO> queryScoreDetail(Long modelId, String name, String code) throws Exception {

		ModelScDTO modelDTO = (ModelScDTO) modelService.getById(modelId);

		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("parentId", "0");
		condition.put("modelId", modelDTO.getModelId());
		List<QuotaDO> quotaList = quotaService.findQuotaList(condition);

		if (Constant.MODEL_TYPE_LEGAL_PERSON == modelDTO.getModelType()) {
			return this.getLegalModelScoreDetail(modelDTO, name, code, quotaList);
		} else if (Constant.MODEL_TYPE_NATURAL_PERSON == modelDTO.getModelType()) {
			return this.getNaturalModelScoreDetail(modelDTO, name, code, quotaList);
		} else {
			return new ArrayList<ScoreDTO>();
		}
	}

	/**
	 * 获取法人模型评分结果
	 * 
	 * @param modelDTO
	 * @param name
	 * @param code
	 * @param quotaList
	 * @return
	 * @throws Exception
	 */
	protected List<ScoreDTO> getLegalModelScoreDetail(ModelScDTO modelDTO, String name, String code,
			List<QuotaDO> quotaList) throws Exception {
		List<ScoreDTO> scoreList = new ArrayList<ScoreDTO>();

		List<BaseLegalPersonDO> list = baseLegalPersonService.getLegalPerson(name, code);
		String personId = "";
		if (null != list && list.size() > 0) {
			BaseLegalPersonDO baseLegalPersonDO = list.get(0);
			personId = baseLegalPersonDO.getLegalPersonId();
		}

		if (!StringUtils.isEmpty(personId)) {
			BigDecimal total = new BigDecimal("0");
			ScoreDTO scoreDTO = null;

			scoreDTO = new ScoreDTO();
			scoreDTO.setId(new Long("-2"));
			scoreDTO.setModelName("初始分");
			scoreDTO.setScore(String.valueOf(modelDTO.getScoreInit()));
			scoreDTO.setParentId(new Long("-1"));
			scoreDTO.setName(name);
			scoreDTO.setCode(code);
			scoreList.add(scoreDTO);

			JdbcManager jdbcManager = new JdbcManager();
			String scoreSQL = "select quota_id,score from oms_legal_score_" + modelDTO.getModelId()
					+ " where legal_person_id = ? and quota_id = ?";

			for (QuotaDO quotaDO : quotaList) {
				List<Map<String, Object>> result = jdbcManager.executeQuery(
						this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), scoreSQL,
						new Object[] { personId, quotaDO.getQuotaId() });
				if (null != result && result.size() > 0) {
					Map<String, Object> map = result.get(0);
					String score = (String) map.get("score");
					scoreDTO = new ScoreDTO();
					scoreDTO.setId(quotaDO.getQuotaId());
					scoreDTO.setModelName(quotaDO.getQuotaName());
					scoreDTO.setScore(score);
					scoreDTO.setParentId(new Long("-1"));
					scoreDTO.setName(name);
					scoreDTO.setCode(code);

					scoreList.add(scoreDTO);

					total = total.add(new BigDecimal(score));

					Map<String, Object> condition = new HashMap<String, Object>();
					condition.put("parentId", quotaDO.getQuotaId());
					condition.put("modelId", modelDTO.getModelId());
					List<QuotaDO> quotaChildList = quotaService.findQuotaList(condition);
					for (QuotaDO quotaChildDO : quotaChildList) {
						List<Map<String, Object>> childResult = jdbcManager.executeQuery(
								this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), scoreSQL,
								new Object[] { personId, quotaChildDO.getQuotaId() });
						if (null != childResult && childResult.size() > 0) {
							Map<String, Object> childMap = childResult.get(0);
							scoreDTO = new ScoreDTO();
							scoreDTO.setId(quotaChildDO.getQuotaId());
							scoreDTO.setModelName(quotaChildDO.getQuotaName());
							scoreDTO.setScore((String) childMap.get("score"));
							scoreDTO.setParentId(quotaChildDO.getParentId());
							scoreDTO.setName(name);
							scoreDTO.setCode(code);

							scoreList.add(scoreDTO);
						}
					}
				}
			}

			total = total.add(new BigDecimal(modelDTO.getScoreInit()));
			scoreDTO = new ScoreDTO();
			scoreDTO.setId(new Long(-1));
			scoreDTO.setModelName(modelDTO.getModelName());
			scoreDTO.setScore(total.toString());
			scoreDTO.setParentId(new Long(0));
			scoreDTO.setName(name);
			scoreDTO.setCode(code);
			scoreList.add(scoreDTO);

		}

		return scoreList;
	}

	/**
	 * 获取自然人模型评分结果详情
	 * 
	 * @param modelDTO
	 * @param name
	 * @param code
	 * @param quotaList
	 * @return
	 * @throws Exception
	 */
	protected List<ScoreDTO> getNaturalModelScoreDetail(ModelScDTO modelDTO, String name, String code,
			List<QuotaDO> quotaList) throws Exception {
		List<ScoreDTO> scoreList = new ArrayList<ScoreDTO>();

		List<BaseNaturalPersonDO> list = baseNaturalPersonService.getNaturalPerson(name,
				StringUtils.encodeIdCard(code));
		String personId = "";
		if (null != list && list.size() > 0) {
			BaseNaturalPersonDO baseNaturalPersonDO = list.get(0);
			personId = baseNaturalPersonDO.getNaturalPersonId();
		}

		BigDecimal total = new BigDecimal("0");
		ScoreDTO scoreDTO = null;

		scoreDTO = new ScoreDTO();
		scoreDTO.setId(new Long("-2"));
		scoreDTO.setModelName("初始分");
		scoreDTO.setScore(String.valueOf(modelDTO.getScoreInit()));
		scoreDTO.setParentId(new Long("-1"));
		scoreDTO.setName(name);
		scoreDTO.setCode(StringUtils.idMask(code, 3, 3));
		scoreList.add(scoreDTO);

		if (!StringUtils.isEmpty(personId)) {
			JdbcManager jdbcManager = new JdbcManager();
			String scoreSQL = "select quota_id,score from oms_natural_score_" + modelDTO.getModelId()
					+ " where natural_person_id = ? and quota_id = ?";

			for (QuotaDO quotaDO : quotaList) {
				List<Map<String, Object>> result = jdbcManager.executeQuery(
						this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), scoreSQL,
						new Object[] { personId, quotaDO.getQuotaId() });
				if (null != result && result.size() > 0) {
					Map<String, Object> map = result.get(0);
					String score = (String) map.get("score");
					scoreDTO = new ScoreDTO();
					scoreDTO.setId(quotaDO.getQuotaId());
					scoreDTO.setModelName(quotaDO.getQuotaName());
					scoreDTO.setScore(score);
					scoreDTO.setParentId(new Long("-1"));
					scoreDTO.setName(name);
					scoreDTO.setCode(StringUtils.idMask(code, 3, 3));

					scoreList.add(scoreDTO);

					total.add(new BigDecimal(score));

					Map<String, Object> condition = new HashMap<String, Object>();
					condition.put("parentId", quotaDO.getQuotaId());
					condition.put("modelId", modelDTO.getModelId());
					List<QuotaDO> quotaChildList = quotaService.findQuotaList(condition);
					for (QuotaDO quotaChildDO : quotaChildList) {
						List<Map<String, Object>> childResult = jdbcManager.executeQuery(
								this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), scoreSQL,
								new Object[] { personId, quotaChildDO.getQuotaId() });
						if (null != childResult && childResult.size() > 0) {
							Map<String, Object> childMap = childResult.get(0);
							scoreDTO = new ScoreDTO();
							scoreDTO.setId(quotaChildDO.getQuotaId());
							scoreDTO.setModelName(quotaChildDO.getQuotaName());
							scoreDTO.setScore((String) childMap.get("score"));
							scoreDTO.setParentId(quotaChildDO.getParentId());
							scoreDTO.setName(name);
							scoreDTO.setCode(StringUtils.idMask(code, 3, 3));

							scoreList.add(scoreDTO);
						}
					}
				}
			}

		}
		scoreDTO = new ScoreDTO();
		scoreDTO.setId(new Long(-1));
		scoreDTO.setParentId(new Long(0));
		scoreDTO.setModelName(modelDTO.getModelName());
		scoreDTO.setScore(total.toString());
		scoreDTO.setName(name);
		scoreDTO.setCode(StringUtils.idMask(code, 3, 3));
		scoreList.add(scoreDTO);

		return scoreList;
	}

	/**
	 * 查询信用分详情
	 * 
	 * @param modelId 模型ID
	 * @param name    法人名称/自然人姓名
	 * @param code    统一社会信用代码/自然人身份证号码
	 * @throws Exception
	 */
	public ScoreDTO queryScore(Long modelId, String name, String code) throws Exception {

		ModelScDTO modelDTO = (ModelScDTO) modelService.getById(modelId);

		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("parentId", "0");
		condition.put("modelId", modelDTO.getModelId());
		List<QuotaDO> quotaList = quotaService.findQuotaList(condition);

		if (Constant.MODEL_TYPE_LEGAL_PERSON == modelDTO.getModelType()) {
			return this.getLegalModelScore(modelDTO, name, code, quotaList);
		} else if (Constant.MODEL_TYPE_NATURAL_PERSON == modelDTO.getModelType()) {
			return this.getNaturalModelScore(modelDTO, name, code, quotaList);
		} else {
			return new ScoreDTO();
		}
	}

	/**
	 * 获取法人模型评分结果
	 * 
	 * @param modelDTO
	 * @param name
	 * @param code
	 * @param quotaList
	 * @return
	 * @throws Exception
	 */
	protected ScoreDTO getLegalModelScore(ModelScDTO modelDTO, String name, String code, List<QuotaDO> quotaList)
			throws Exception {
		ScoreDTO scoreDTO = new ScoreDTO();
		scoreDTO.setName(name);
		scoreDTO.setCode(code);
		scoreDTO.setScoreTotal(modelDTO.getScoreTotal() + "");

		List<BaseLegalPersonDO> list = baseLegalPersonService.getLegalPerson(name, code);
		String personId = "";
		if (null != list && list.size() > 0) {
			BaseLegalPersonDO baseLegalPersonDO = list.get(0);
			personId = baseLegalPersonDO.getLegalPersonId();
		}
		BigDecimal total = new BigDecimal("0");
		if (!StringUtils.isEmpty(personId)) {
			JdbcManager jdbcManager = new JdbcManager();
			String scoreSQL = "select quota_id,score from oms_legal_score_" + modelDTO.getModelId()
					+ " where legal_person_id = ? and quota_id = ?";

			for (QuotaDO quotaDO : quotaList) {
				List<Map<String, Object>> result = jdbcManager.executeQuery(
						this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), scoreSQL,
						new Object[] { personId, quotaDO.getQuotaId() });
				if (null != result && result.size() > 0) {
					Map<String, Object> map = result.get(0);
					String score = (String) map.get("score");

					total = total.add(new BigDecimal(score));

					Map<String, Object> condition = new HashMap<String, Object>();
					condition.put("parentId", quotaDO.getQuotaId());
					condition.put("modelId", modelDTO.getModelId());
				}
			}
		}
		total = total.add(new BigDecimal(modelDTO.getScoreInit()));
		if (total.compareTo(new BigDecimal(0)) < 0) {
			total  = new BigDecimal(0);
		}
		scoreDTO.setModelName(modelDTO.getModelName());
		scoreDTO.setScore(total.toString());

		Map<String, Object> scoreCondition = new HashMap<String, Object>();
		scoreCondition.put("scoreId", modelDTO.getScoreId());
		List<ScoreLevelDetailDO> levelDetailList = scoreLevelDetailService.list(scoreCondition);
		for (ScoreLevelDetailDO scoreLevelDetailDO : levelDetailList) {
			total.subtract(new BigDecimal(scoreLevelDetailDO.getLevelDown()));
			if (total.compareTo(new BigDecimal(scoreLevelDetailDO.getLevelDown())) >= 0
					&& total.compareTo(new BigDecimal(scoreLevelDetailDO.getLevelUp())) < 0) {
				scoreDTO.setLevelName(scoreLevelDetailDO.getLevelName());
				scoreDTO.setLevelDesc(scoreLevelDetailDO.getLevelDesc());
				break;
			}
		}
		return scoreDTO;
	}

	/**
	 * 获取自然人模型评分结果详情
	 * 
	 * @param modelDTO
	 * @param name
	 * @param code
	 * @param quotaList
	 * @return
	 * @throws Exception
	 */
	protected ScoreDTO getNaturalModelScore(ModelScDTO modelDTO, String name, String code, List<QuotaDO> quotaList)
			throws Exception {
		ScoreDTO scoreDTO = new ScoreDTO();
		scoreDTO.setScoreTotal(modelDTO.getScoreTotal() + "");

		List<BaseNaturalPersonDO> list = baseNaturalPersonService.getNaturalPerson(name, StringUtils.encodeIdCard(code));
		String personId = "";
		if (null != list && list.size() > 0) {
			BaseNaturalPersonDO baseNaturalPersonDO = list.get(0);
			personId = baseNaturalPersonDO.getNaturalPersonId();
			scoreDTO.setName(baseNaturalPersonDO.getName());
			scoreDTO.setCode(StringUtils.idMask(baseNaturalPersonDO.getIdCard(), 3, 3));
		}

		BigDecimal total = new BigDecimal("0");

		if (!StringUtils.isEmpty(personId)) {
			JdbcManager jdbcManager = new JdbcManager();
			String scoreSQL = "select quota_id,score from oms_natural_score_" + modelDTO.getModelId()
					+ " where natural_person_id = ? and quota_id = ?";

			for (QuotaDO quotaDO : quotaList) {
				List<Map<String, Object>> result = jdbcManager.executeQuery(this.getDBConnection(Constant.SOURCE_CODE_BASESOURCE), scoreSQL,
						new Object[] { personId, quotaDO.getQuotaId() });
				if (null != result && result.size() > 0) {
					Map<String, Object> map = result.get(0);
					String score = (String) map.get("score");
					total = total.add(new BigDecimal(score));
				}
			}

		}
		total = total.add(new BigDecimal(modelDTO.getScoreInit()));
		if (total.compareTo(new BigDecimal(0)) < 0) {
			total  = new BigDecimal(0);
		}
		scoreDTO = new ScoreDTO();
		scoreDTO.setModelName(modelDTO.getModelName());
		scoreDTO.setScore(total.toString());

		Map<String, Object> scoreCondition = new HashMap<String, Object>();
		scoreCondition.put("scoreId", modelDTO.getScoreId());
		List<ScoreLevelDetailDO> levelDetailList = scoreLevelDetailService.list(scoreCondition);
		for (ScoreLevelDetailDO scoreLevelDetailDO : levelDetailList) {
			total.subtract(new BigDecimal(scoreLevelDetailDO.getLevelDown()));
			if (total.compareTo(new BigDecimal(scoreLevelDetailDO.getLevelDown())) >= 0
					&& total.compareTo(new BigDecimal(scoreLevelDetailDO.getLevelUp())) < 0) {
				scoreDTO.setLevelName(scoreLevelDetailDO.getLevelName());
				scoreDTO.setLevelDesc(scoreLevelDetailDO.getLevelDesc());
				break;
			}
		}

		return scoreDTO;
	}
	
}
